package org.linlinjava.litemall.core.inventory;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.checkerframework.checker.units.qual.A;
import org.linlinjava.litemall.core.inventory.bean.EquBindingHomePile;
import org.linlinjava.litemall.core.qcode.QCodeService;
import org.linlinjava.litemall.core.util.InventoryStringAssembleUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.config.CenterServerAddress;
import org.linlinjava.litemall.db.config.ServerAddress;
import org.linlinjava.litemall.db.dao.*;
import org.linlinjava.litemall.db.dao.order_manage.AgedmallLocksMapper;
import org.linlinjava.litemall.db.dao.order_manage.AgedmallShopMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.util.WechatUtil;
import org.linlinjava.litemall.db.vo.shop.StoreGoodsInventoryDto;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author wj
 * @date 2021/9/28 15:02
 */
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class InventoryService {
    private final Log logger = LogFactory.getLog(QCodeService.class);
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private LitemallOrderMapper litemallOrderMapper;

    @Resource
    private LitemallOrderGoodsMapper litemallOrderGoodsMapper;

    @Resource
    private AgedmallCloudHouseMapper agedmallCloudHouseMapper;

    @Resource
    private AgedmallCloudGoodsProductMapper agedmallCloudGoodsProductMapper;

    @Resource
    private AgedmallStoreMapper agedmallStoreMapper;

    @Resource
    private AgedmallShopMapper agedmallShopMapper;

    @Resource
    private AgedmallGoodsEquMapper agedmallGoodsEquMapper;

    @Resource
    private AgedmallLocksMapper agedmallLocksMapper;

    @Resource
    private ServerAddress serverAddress;

    @Resource
    private WechatUtil wechatUtil;

    @Resource
    private AgedmallStoreGoodsMapper agedmallStoreGoodsMapper;

    /**
     * 获取门店软链和桩位的绑定关系
     *
     * @param storeId
     */
    public void refreshBindingEquAndHomePile(Integer storeId) {
        AgedmallGoodsEquExample goodsEquExample = new AgedmallGoodsEquExample();
        goodsEquExample.createCriteria().andTypeEqualTo(0).andStoreIdEqualTo(storeId.longValue()).andDeletedEqualTo((byte)0);
        goodsEquExample.or().andTypeEqualTo(2).andStoreIdEqualTo(storeId.longValue()).andDeletedEqualTo((byte)0);
        List<AgedmallGoodsEqu> goodsEqus = agedmallGoodsEquMapper.selectByExample(goodsEquExample);
        List<Integer> equIdList = new ArrayList<>();
        goodsEqus.forEach(goodsEqu -> equIdList.add(goodsEqu.getEquId().intValue()));
        if (!equIdList.isEmpty()) {
            String result = HttpRequest.post(serverAddress.getCenter() + "admin_api/EquBingingRelation")
                    //头信息，多个头信息多次调用此方法即可
                    .header(CenterServerAddress.KEY_HEADER_STRING, CenterServerAddress.KEY_SECUREUTIL_MD5)
                    .body(JSON.toJSONString(equIdList))
                    .timeout(50000)//超时，毫秒
                    .execute().body();
            JSONObject jsonObject = JSON.parseObject(result);
            JSONArray bindingHomePile = JSONArray.parseArray(JSON.toJSONString(jsonObject.get("data")));
            if (null != bindingHomePile) {
                for (int i = 0; i < bindingHomePile.size(); i++) {
                    for (int j = 0; j < goodsEqus.size(); j++) {
                        if (goodsEqus.get(j).getEquId().intValue() == (int) bindingHomePile.getJSONObject(i).get("equId")) {
                           Integer hpId= bindingHomePile.getJSONObject(i).get("hpId")==null?null:Integer.parseInt(bindingHomePile.getJSONObject(i).get("hpId").toString());
                            goodsEqus.get(j).setHpId(hpId);
                            agedmallGoodsEquMapper.updateByPrimaryKey(goodsEqus.get(j));
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取一个门店所有商品的库存
     *
     * @param storeId
     * @param type
     */
    public Object getStoreInventoryByStoreId(Integer storeId, Integer type) {
        refreshBindingEquAndHomePile(storeId);
        //门店
        if (type == 0) {
            //获取门店本身的库存
            List<StoreGoodsInventoryDto> storeGoodsInventory = agedmallShopMapper.getStoreGoodsInventory(storeId);
            //根据商品id分组
            Map<Integer, List<StoreGoodsInventoryDto>> storeGroupByGoodsId = storeGoodsInventory.stream().collect(Collectors.groupingBy(StoreGoodsInventoryDto::getGoodsId));
            storeGroupByGoodsId.entrySet().forEach(entry -> {
                List<StoreGoodsInventoryDto> goodsList = entry.getValue();
                if (!goodsList.isEmpty()) {
                    StoreGoodsInventoryDto oneStoreGoods = goodsList.get(0);
                    String key = InventoryStringAssembleUtil.assembleKey(oneStoreGoods.getStoreId(), 0, 0,
                            entry.getKey(), null);
                    Integer goodsCount = 0;
                    for (int i = 0; i < goodsList.size(); i++) {
                        goodsCount += goodsList.get(i).getGoodsStock();
                    }
                    stringRedisTemplate.opsForValue().set(key, goodsCount.toString());
                }
            });

            //根据商品规格id分组
            Map<Integer, List<StoreGoodsInventoryDto>> storeGroupBySpecId = storeGoodsInventory.stream().collect(Collectors.groupingBy(StoreGoodsInventoryDto::getSpecId));
            storeGroupBySpecId.entrySet().forEach(entry -> {
                List<StoreGoodsInventoryDto> goodsSpecList = entry.getValue();
                if (!goodsSpecList.isEmpty()) {
                    StoreGoodsInventoryDto oneStoreGoodsSpec = goodsSpecList.get(0);
                    String key = InventoryStringAssembleUtil.assembleKey(oneStoreGoodsSpec.getStoreId(), 0, 0,
                            oneStoreGoodsSpec.getGoodsId(), oneStoreGoodsSpec.getSpecId());
                    stringRedisTemplate.opsForValue().set(key, oneStoreGoodsSpec.getGoodsStock().toString());

                    if(oneStoreGoodsSpec.getGoodsStock()>0){
                        //发送到货通知
                        wechatUtil.sendSubscribeMessage(oneStoreGoodsSpec.getStoreId().longValue(),oneStoreGoodsSpec.getGoodsId().longValue(), oneStoreGoodsSpec.getSpecId().longValue(),oneStoreGoodsSpec.getGoodsStock());
                    }
                }
            });


            //获取链条锁库存
            AgedmallGoodsEquExample goodsEquExample = new AgedmallGoodsEquExample();
            goodsEquExample.or().andDeletedEqualTo((byte) 0).andTypeEqualTo(0).
                    andStateEqualTo(0).andStoreIdEqualTo(storeId.longValue()).andHpIdIsNotNull().andHpIdNotEqualTo(0);
            List<AgedmallGoodsEqu> equs = agedmallGoodsEquMapper.selectByExample(goodsEquExample);
            //根据商品id分组
            Map<Long, List<AgedmallGoodsEqu>> equGroupByGoodsId = equs.stream().collect(Collectors.groupingBy(AgedmallGoodsEqu::getGoodsId));
            //增加整个商品的库存
            equGroupByGoodsId.entrySet().forEach(entry -> {
                Integer goodsCount;
                List<AgedmallGoodsEqu> goodsEqu = entry.getValue();
                if (!goodsEqu.isEmpty()) {
                    AgedmallGoodsEqu oneEqu = goodsEqu.get(0);
                    goodsCount = goodsEqu.size();
                    String key = InventoryStringAssembleUtil.assembleKey(oneEqu.getStoreId().intValue(), 0, 1,
                            entry.getKey().intValue(), null);

                    stringRedisTemplate.opsForValue().set(key, goodsCount.toString());
                }
            });
            //根据商品规格id分组
            Map<Long, List<AgedmallGoodsEqu>> equGroupBySpec = equs.stream().collect(Collectors.groupingBy(AgedmallGoodsEqu::getGoodsProductId));
            //增加整个商品规格的库存
            equGroupBySpec.entrySet().forEach(entry -> {
                Integer goodsCount;
                List<AgedmallGoodsEqu> goodsEqu = entry.getValue();
                if (!goodsEqu.isEmpty()) {
                    AgedmallGoodsEqu oneEqu = goodsEqu.get(0);
                    goodsCount = goodsEqu.size();
                    String key = InventoryStringAssembleUtil.assembleKey(oneEqu.getStoreId().intValue(), 0, 1,
                            oneEqu.getGoodsId().intValue(), entry.getKey().intValue());
                    stringRedisTemplate.opsForValue().set(key, goodsCount.toString());
                    if(goodsCount>0){
                        //发送到货通知
                        wechatUtil.sendSubscribeMessage(oneEqu.getStoreId(),oneEqu.getGoodsId(), entry.getKey(),goodsCount);
                    }
                }
            });

            //获取衣柜锁库存
            List<StoreGoodsInventoryDto> cabinetGoodsInventory = agedmallLocksMapper.getCabinetGoodsInventory(storeId);
            //根据商品id分组
            Map<Integer, List<StoreGoodsInventoryDto>> cabinetGoodsGroupByGoods = cabinetGoodsInventory
                    .stream().collect(Collectors.groupingBy(StoreGoodsInventoryDto::getGoodsId));
            //增加整个商品的库存
            cabinetGoodsGroupByGoods.entrySet().forEach(entry -> {
                Integer goodsCount;
                List<StoreGoodsInventoryDto> cabinetGoods = entry.getValue();
                if (!cabinetGoods.isEmpty()) {
                    StoreGoodsInventoryDto oneEqu = cabinetGoods.get(0);
                    goodsCount = cabinetGoods.size();
                    String key = InventoryStringAssembleUtil.assembleKey(oneEqu.getStoreId(), 0, 2,
                            entry.getKey(), null);

                    stringRedisTemplate.opsForValue().set(key, goodsCount.toString());
                }
            });
            //根据商品规格id分组
            Map<Integer, List<StoreGoodsInventoryDto>> cabinetGoodsGroupBySpec = cabinetGoodsInventory
                    .stream().collect(Collectors.groupingBy(StoreGoodsInventoryDto::getSpecId));
            //增加整个商品规格的库存
            cabinetGoodsGroupBySpec.entrySet().forEach(entry -> {
                Integer goodsCount;
                List<StoreGoodsInventoryDto> goodsEqu = entry.getValue();
                if (!goodsEqu.isEmpty()) {
                    StoreGoodsInventoryDto oneEqu = goodsEqu.get(0);
                    goodsCount = goodsEqu.size();
                    String key = InventoryStringAssembleUtil.assembleKey(oneEqu.getStoreId(), 0, 2,
                            oneEqu.getGoodsId(), entry.getKey());
                    stringRedisTemplate.opsForValue().set(key, goodsCount.toString());
                    if(goodsCount>0){
                        //发送到货通知
                        wechatUtil.sendSubscribeMessage(oneEqu.getStoreId().longValue(),oneEqu.getGoodsId().longValue(), entry.getKey().longValue(),goodsCount);
                    }
                }
            });

        } else if (type == 1) {

            AgedmallCloudGoodsProductExample goodsProductExample = new AgedmallCloudGoodsProductExample();
            goodsProductExample.or().andCloudIdEqualTo(storeId.longValue());
            List<AgedmallCloudGoodsProduct> agedmallCouldGoodsProducts = agedmallCloudGoodsProductMapper.selectByExample(goodsProductExample);
            //根据商品id分组
            Map<Long, List<AgedmallCloudGoodsProduct>> cloudGoodsGroupByGoods = agedmallCouldGoodsProducts
                    .stream().collect(Collectors.groupingBy(AgedmallCloudGoodsProduct::getGoodsId));
            //增加整个商品的库存
            cloudGoodsGroupByGoods.entrySet().forEach(entry -> {
                //获取当前门店选择的云仓列表
                AgedmallStoreGoodsExample storeGoodsExample=new AgedmallStoreGoodsExample();
                storeGoodsExample.createCriteria().andDeletedEqualTo(false).andGoodsIdEqualTo(entry.getKey()).
                        andStoreIdEqualTo(storeId.longValue());
                AgedmallStoreGoods storeGoods = agedmallStoreGoodsMapper.selectOneByExample(storeGoodsExample);
                List<Integer> canUseCloudId=new ArrayList<>();
                if(ObjectUtil.isNotNull(storeGoods)&&StringUtils.isNotBlank(storeGoods.getCloudId())){
                    String[] couldIdArray=storeGoods.getCloudId().split(",");
                    Arrays.stream(couldIdArray).forEach(could->canUseCloudId.add(Integer.parseInt(could)));
                }

                Integer goodsCount = 0;
                List<AgedmallCloudGoodsProduct> cabinetGoods = entry.getValue();
                if (!cabinetGoods.isEmpty()) {
                    AgedmallCloudGoodsProduct oneEqu = cabinetGoods.get(0);
                    for (int i = 0; i < cabinetGoods.size(); i++) {
                        if(canUseCloudId.size()>0){
                            if(canUseCloudId.contains(cabinetGoods.get(i).getCloudId().intValue())){
                                goodsCount += cabinetGoods.get(i).getProductStock();
                            }
                        }
                        else{
                            goodsCount += cabinetGoods.get(i).getProductStock();
                        }
                    }
                    String key = InventoryStringAssembleUtil.assembleKey(oneEqu.getCloudId().intValue(), 1, 3,
                            entry.getKey().intValue(), null);
                    stringRedisTemplate.opsForValue().set(key, goodsCount.toString());
                }
            });
            //根据商品规格id分组
            Map<Long, List<AgedmallCloudGoodsProduct>> cloudGoodsGroupBySpec = agedmallCouldGoodsProducts
                    .stream().collect(Collectors.groupingBy(AgedmallCloudGoodsProduct::getGoodsProductId));
            //增加整个商品规格的库存
            cloudGoodsGroupBySpec.entrySet().forEach(entry -> {
                Integer goodsCount = 0;
                List<AgedmallCloudGoodsProduct> goodsEqu = entry.getValue();
                if (!goodsEqu.isEmpty()) {
                    AgedmallCloudGoodsProduct oneEqu = goodsEqu.get(0);
                    AgedmallStoreGoodsExample storeGoodsExample=new AgedmallStoreGoodsExample();
                    storeGoodsExample.createCriteria().andDeletedEqualTo(false).andGoodsIdEqualTo(oneEqu.getGoodsId()).
                            andStoreIdEqualTo(storeId.longValue());
                    AgedmallStoreGoods storeGoods = agedmallStoreGoodsMapper.selectOneByExample(storeGoodsExample);
                    List<Integer> canUseCloudId=new ArrayList<>();
                    if(ObjectUtil.isNotNull(storeGoods)&&StringUtils.isNotBlank(storeGoods.getCloudId())){
                        String[] couldIdArray=storeGoods.getCloudId().split(",");
                        Arrays.stream(couldIdArray).forEach(could->canUseCloudId.add(Integer.parseInt(could)));
                    }
                    if(canUseCloudId.size()>0){
                        if(canUseCloudId.contains(oneEqu.getCloudId().intValue())){
                            goodsCount = oneEqu.getProductStock();
                        }
                    }
                    else{
                        goodsCount = oneEqu.getProductStock();
                    }

                    String key = InventoryStringAssembleUtil.assembleKey(oneEqu.getCloudId().intValue(), 1, 3,
                            oneEqu.getGoodsId().intValue(), entry.getKey().intValue());
                    stringRedisTemplate.opsForValue().set(key, goodsCount.toString());

                    if(goodsCount>0){
                        //发送到货通知
                        wechatUtil.sendSubscribeMessage(storeId.longValue(),oneEqu.getGoodsId(), entry.getKey(),goodsCount);
                    }
                }
            });
        } else {
            return ResponseUtil.fail(800, "库存类型不存在");
        }

        return ResponseUtil.ok();
    }


}
